var Ble = function() {};
var bleCode = [];
var bleCode_index = 0;
var bleInited = false;
var bleStatus = false;
var bleTarget = "";
var bleTransfer;
var bleAjax;
var bleTimeout = 1;
var bleInfo = {
    STAUS_INIT: "页面正在初始化，请稍后再尝试",
    STAUS_BLUETOOTH_OFF: "请开启手机蓝牙模块",
    STAUS_BLUETOOTH_UNAUTHORIZED: "您还没有授权微信使用蓝牙功能",
    MISS_BLUETOOTH_DEVICE: "没有连接上设备，请重试",
    Require_GPS_Service_On: "该版本安卓系统需要打开GPS服务，请重试",
    IsJxEtcCard: "非江西省ETC卡",
    BLUETOOTH_SEARCHING: "正在搜索蓝牙····，请勿关闭OBU",
    BLUETOOTH_STOP_SEARCHING: "蓝牙设备搜索完成，如找不到设备请关闭重试！",
    OPERATION_TIMEOUT: "连接蓝牙盒子超时，请重试",
    CARDNO_DIFFERENT: "卡号与所选卡片不一致",
    NET_TIMEOUT :"网络异常，请稍后重试！",
    SERVER_ERROR :"服务器异常，请稍后重试！"

};
var carTypeArray = ["", "储值卡", "记账卡"];
var paymentConfirmTimes = 0;

Ble.prototype = {

    bleInit: function(opts, func) {
        this.bleInit_UI(opts);
        this.bleInit_WX(opts, func);
    },
    //初始化UI
    bleInit_UI: function(opts) {
        if(opts.timeout){
            bleTimeout = opts.timeout;
        }
        //蓝牙列表弹窗text
        var bluListText = "<div class='query_find_blue none'> <i class='query_close'></i>" + "<div class='find_blue_top'>" + "<h3 class='status-text'>正在搜索蓝牙····，请勿关闭OBU</h3></div>" + "<div class='bluetooth_list'>" + "<div class='hasMatched'></div>" + "<div class='unMatched'></div></div>" + "<div class='nextStep disable'></div></div>";
        //读卡中弹窗text
        var readCardList = "<div class='query_read_box none'><i class='query_close'></i><h1><hr><span></span></h1><h3>正在识别蓝牙中<br/>请勿拔卡或移动卡片</h3></div>";
        //圈存弹窗
        var transferText = "<div class='debbting_box none'><img src='img/debitting.png'><h3 class='debbting_body'><hr><span></span>正在进行读卡圈存····<br>请勿移动卡片 !</h3></div>";
        $(".mask_layer").html(bluListText + readCardList + transferText);
    },

    maskBoxShow: function(cls) {
        ble.counter = {};
        if(cls == "debbting_box"){
            ble.counter.waitTime = ble.counter.totalTime = 60000 * bleTimeout;
        }else{
            ble.counter.waitTime = ble.counter.totalTime = 30000 * bleTimeout;
        }
        ble.counter.line = $("." + cls + " hr");
        ble.counter.over = false;
        ble.countdown();
        $(".mask_layer > div").addClass('none');
        $(".mask_layer, ." + cls).removeClass('none');
    },

    countdown: function() {
        clearTimeout(ble.timeout);
        if (ble.counter.waitTime == 0) {
            if (!ble.counter.over) {

                //计时完啦
                $(".mask_layer, .mask_layer > div").addClass('none');
                alert_LHX({
                    hasBtn: 1,
                    msg: bleInfo.OPERATION_TIMEOUT
                });
            }
        } else {
            ble.counter.waitTime -= 100;
            var per = Math.round(ble.counter.waitTime / ble.counter.totalTime * 10000) / 100.00 + "%";
            ble.counter.line.css("width", per);
            ble.timeout = setTimeout(function() {
                ble.countdown();
            }, 100);
        }
    },
    resetCountdown: function () {
        ble.counter.waitTime = 20000 * bleTimeout;
    },
    countover: function() {
        if(ble.counter) ble.counter.over = true;
    },

    //初始化微信配置
    bleInit_WX: function(opts, func) {
        this.opts = opts;
        wx.config({
            beta: true, //坑：这个很重要，必须配置这个为true,才能调用微信的硬件API
            debug: true, //是否开启调试模式，会自动弹一些消息框显示微信返回的数据
            appId: opts.appId,
            timestamp: opts.timestamp,
            nonceStr: opts.nonceStr,
            signature: opts.signature,
            jsApiList: [ //需要调用的接口，都得在这里面写一遍
                "openWXDeviceLib", //初始化设备库（只支持蓝牙设备）
                "closeWXDeviceLib", //关闭设备库（只支持蓝牙设备）
                "getWXDeviceInfos", //获取设备信息（获取当前用户已绑定的蓝牙设备列表）
                "sendDataToWXDevice", //发送数据给设备
                "startScanWXDevice", //扫描设备（获取周围所有的设备列表，无论绑定还是未被绑定的设备都会扫描到）
                "stopScanWXDevice", //停止扫描设备
                "connectWXDevice", //连接设备
                "disconnectWXDevice", //断开设备连接
                "getWXDeviceTicket", //获取操作凭证
                //下面是监听事件：
                "onWXDeviceBindStateChange", //微信客户端设备绑定状态被改变时触发此事件
                "onWXDeviceStateChange", //监听连接状态，可以监听连接中、连接上、连接断开
                "onReceiveDataFromWXDevice", //接收到来自设备的数据时触发
                "onScanWXDeviceResult", //扫描到某个设备时触发
                "onWXDeviceBluetoothStateChange", //手机蓝牙打开或关闭时触发   
                "chooseWXPay",
            ]
        });
        wx.ready(function() {

            ble.openWXDeviceLib();

            wx.on('onScanWXDeviceResult', function(res) {
                $(".unMatched").html("");
                for (var i = 0; i < res.devices.length; i++) {
                    var macid = JSON.stringify(res.devices[i].deviceId).replace(/\"/g, "");
                    var m = macid.split("_");
                    if ($("#" + macid).length > 0) {
                        continue;
                    }
                    $(".unMatched").append("<p onclick=\"ble.bindBle('" + macid + "')\" data-id=" + macid + ">" + m[2] + "</p>");
                }
            });

            //手机蓝牙状态改变时触发
            wx.on('onWXDeviceBluetoothStateChange', function(res) {
                if (res.state == "on") {
                    bleStatus = true;
                } else {
                    bleStatus = false;
                }
            });

            //设备绑定状态改变事件（解绑\绑定成功的瞬间触发）
            wx.on('onWXDeviceBindStateChange', function(res) {
                //$("#info").append("<p>绑定状态变更：" + JSON.stringify(res) + "</p>");
            });

            //设备连接状态改变
            wx.on('onWXDeviceStateChange', function(res) {
                //有3个状态：connecting连接中,connected已连接,unconnected未连接
                //每当手机和设备之间的状态改变的瞬间，会触发一次
                var state = res.state;
                if (state === "connected" || state === "disconnected") {
                    var p = $("#" + res.deviceId),
                        c = "";
                    if (p.hasClass(state)) return;
                    if (p.hasClass("hasBind")) {
                        c = "hasBind ";
                        if (state === "connected") {
                            $(".nextStep").removeClass('disable');
                        } else {
                            $(".nextStep").addClass('disable');
                        }
                    }
                    p.attr("class", c + state);
                }
            });

            //接收到设备传来的数据
            wx.on('onReceiveDataFromWXDevice', function(res) {
                ble.dismantleData(decode(res.base64Data));
            });

            wx.error(function(res) {
                alert_LHX({
                    hasBtn: 0,
                    msg: "未获取到信息，请退出再重新进入页面！"
                });
            });
        });
    },
    openWXDeviceLib: function() {
        wx.invoke('openWXDeviceLib', {}, function(res) {
            bleInited = res.err_msg == "openWXDeviceLib:ok" ? true : false;
            if (res.bluetoothState == "on") {
                bleStatus = true;
            } else if (res.bluetoothState == "off") {
                bleStatus = false;
            } else if (res.bluetoothState == "unauthorized") {
                alert_LHX({
                    hasBtn: 1,
                    msg: bleInfo.STAUS_BLUETOOTH_UNAUTHORIZED
                });
            }
        });
    },
    getSelectDevice: function() {
        return this.deviceId;
    },
    selectDevice: function(id) {
        this.deviceId = id;
        // 下一步按钮可用
        if ($("#" + id).hasClass("connected")) {
            $(".nextStep").removeClass('disable');
        } else {
            $(".nextStep").addClass('disable');
        }
        // 突出显示该设备
        $(".hasMatched p,.unMatched p").removeClass('hasBind');
        $("#" + id).addClass('hasBind');
    },
    //获取用户绑定的设备
    getWXDeviceInfos: function() {
        wx.invoke('getWXDeviceInfos', {}, function(res) {
            if (res.err_msg == "getWXDeviceInfos:ok") {
                var l = res.deviceInfos.length;
                if (l > 0) {
                    $(".hasMatched").html("");
                    for (var i = 0; i < l; i++) {
                        var macid = res.deviceInfos[i].deviceId;
                        var m = macid.split("_");
                        var h = "<p onclick=\"ble.selectDevice('" + macid + "')\" id=\"" + macid + "\" class=\"";
                        h += res.deviceInfos[i].state + "\">" + m[2];
                        h += "<span style=\"float:right;\" onclick=\"ble.unBindBle('" + macid + "')\">解绑</span></p>";
                        $(".hasMatched").append(h);
                    }
                    if (l == 1) {
                        ble.selectDevice(res.deviceInfos[0].deviceId);
                    }
                    $(".query_find_blue, .mask_layer").removeClass('none');
                }
            } else {
                // alert_LHX({
                //     hasBtn: 1,
                //     msg: "读取用户设备失败，请重试"
                // });
                //alert("读取用户设备失败，请重试");
            }
        });
    },

    bindBle: function(macid) {
        var m = macid.split("_");
        $.post("device/wxCompelBind", {
            "deviceId": macid,
            "openId": this.opts.openId
        }, function(res) {
            if($("#"+macid).size() <= 0){
                $(".unMatched p[data-id=" + macid + "]").remove();
                var h = "<p onclick=\"ble.selectDevice('" + macid + "')\" id=\"" + macid + "\" class=\"disconnected\">" + m[2];
                h += "<span style=\"float:right;\" onclick=\"ble.unBindBle('" + macid + "')\">解绑</span></p>";
                $(".hasMatched").append(h);
                ble.selectDevice(macid);
                //尝试连接设备
                ble.connectWXDevice(macid);
            }

        });
    },

    unBindBle: function(macid) {
        $.post("device/wxCompelUnbind", {
            "deviceId": macid,
            "openId": this.opts.openId
        }, function(res) {
            if($("#"+macid).hasClass("hasBind")){
                $(".nextStep").addClass('disable');
            }
            $("#" + macid).remove();
            //取消连接设备
            ble.disconnectWXDevice(macid);
        });
    },

    //扫描附近的设备
    scanDevice: function() {
        //10秒后自动停止扫描
        setTimeout(function() {
            ble.stopScanDevice();
        }, 10000);

        wx.invoke('startScanWXDevice', {
            'btVersion': 'ble'
        }, function(res) {
            if (res.err_msg == 'startScanWXDevice:fail_ThisAndroidVersionRequireGPSServiceOn') {
                alert_LHX({
                    hasBtn: 1,
                    msg: bleInfo.Require_GPS_Service_On
                });
                // alert(bleInfo.Require_GPS_Service_On);
            } else if (res.err_msg == 'startScanWXDevice:ok') {
                $(".status-text").html(bleInfo.BLUETOOTH_SEARCHING);
            }
        });
    },

    //停止扫描设备
    stopScanDevice: function() {
        wx.invoke('stopScanWXDevice', {}, function(res) {
            if (res.err_msg == 'stopScanWXDevice:ok') {
                $(".status-text").html(bleInfo.BLUETOOTH_STOP_SEARCHING);
            }
        });
    },

    //连接设备(切换设备用)
    connectWXDevice: function(deviceId) {
        wx.invoke('connectWXDevice', {
            'deviceId': deviceId
        }, function(res) {
            if (res.err_msg == 'connectWXDevice:ok') {
                //$("#info").append("<p>连接设备" + deviceId + "成功</p>");
            }
        });
    },

    //断开连接设备
    disconnectWXDevice: function(deviceId) {
        wx.invoke('disconnectWXDevice', {
            'deviceId': deviceId
        }, function(res) {
            if (res.err_msg == 'disconnectWXDevice:ok') {
                //$("#info").append("<p>断开连接设备" + deviceId + "成功</p>");
            }
        });
    },

    //初始化发送指令
    sendDataInit: function(t, arr) {
        bleTarget = t;
        if (arr) {
            bleCode = arr;
        } else {
            var readCardCMD = "c20119008017810700a40000021001020500b09500000305805c000204";
            bleCode = convertToBluetoothProtocol(readCardCMD);
            console.log("readCard:" + bleCode);
        }
        bleCode_index = 0;
        this.sendDataToWXDevice();
    },
    //发送下一条指令
    sendNextData: function() {
        bleCode_index++;
        this.sendDataToWXDevice();
    },

    //发送指令到设备
    sendDataToWXDevice: function() {
        console.log("发送指令");
        console.log(bleCode[bleCode_index]);

        wx.invoke('sendDataToWXDevice', {
            'deviceId': this.deviceId,
            'base64Data': encode(bleCode[bleCode_index])
        }, function(res) {
            console.log(res);
        });
    },

    //拆解指令
    dismantleData: function(data) {
        console.log("收到设备数据：");
        console.log(data);
        if (data.substr(data.length - 6, 4) == "9000") {
            if (ble.recordfile && ble.recordfile.pin && bleTarget == "recordFile") {
                ble.recordfile.tradelists += data.substr(16, 58) + ",";
            }
            if (bleCode_index < bleCode.length - 1) {
                ble.sendNextData();
            } else {
                //得到最终指令
                if (bleTarget == "transfer" && bleTransfer.card) {
                    ble.checkInstru(data);
                } else if (bleTarget == "confirm") {
                    ble.transferConfirm(data);
                } else if (bleTarget == "recordFile") {
                    //alert("send0018Info");
                    ble.send0018Info();
                } else {
                    if (bleTransfer && bleTransfer.success) {
                        if (bleTransfer.handling) {
                            getCardInfo(data.substr(16, data.length - 18));
                        } else {
                            ble.transferSuccess(data.substr(16, data.length - 18));
                        }
                    } else {
                        ble.readCard(data);
                    }
                }
            }
        }
    },

    //获取卡片信息
    readCard: function(data) {
        //判断是否江西卡片
        if (data.substr(32, 4) == "3601") {
            getCardInfo(data.substr(16, data.length - 18)); // 请求后台解析指令
        } else {
            alert_LHX({
                msg: bleInfo.IsJxEtcCard
            });
        }
    },

    //圈存初始化
    transferInit: function(money, isOneStep, isTransfer) {
        //初始化圈存设置
        bleTransfer = {};
        bleTransfer.init = true;
        bleTransfer.money = money;

        bleTransfer.isOneStep = isOneStep;
        bleTransfer.isTransfer = isTransfer;
        //圈存前先读卡
        ble.sendDataInit("transfer");
    },

    //异常处理初始化
    handlingInit: function(billno, amount, callback) {
        //初始化圈存设置
        bleTransfer = {};
        bleTransfer.init = bleTransfer.half = bleTransfer.handling = true;
        bleTransfer.billno = billno;
        bleTransfer.halfmoney = amount;
        bleTransfer.callback = callback;

        ble.sendDataInit("transfer");
    },

    //获取圈存上下限
    queryTransferLimit: function() {
        console.log("获取圈存上下限");
        var sendData = {
            cardNo: bleTransfer.card.cardNo, //卡号
            cardArea: bleTransfer.card.networkNo, //网络号
            balance: bleTransfer.money, //圈存金额
            expiryDate: bleTransfer.card.endTime //有效期
        };

        bleAjaxGet('transfer/queryTransferLimit/', sendData, function(res) {
            switch (res.respCode) {
                case "00":
                    // signature validatiton start --
                    //判断sig, 验证签名
                    if (!res.sig) {
                        alert_LHX({
                            hasBtn: 1,
                            msg: '验证错误'
                        });
                        return;
                    }

                    var return_sig = res.sig;
                    delete res.sig;
                    var default_data = {
                        token: token
                    };
                    var sig = reckonSigGet(default_data, res);
                    if (return_sig != sig) {
                        alert_LHX({
                            hasBtn: 1,
                            msg: '验签失败'
                        });
                        return;
                    }
                    // -- signature validatiton end
                    if (bleTransfer.money > res.rechargeUpperLimit) {
                        alert_LHX({
                            hasBtn: 1,
                            msg: '圈存金额超出上限，请减少圈存金额！'
                        });
                        //bleTransfer.money<res.rechargeDownLimit
                    // } else if (bleTransfer.money <= res.rechargeDownLimit) {
                    } else if (bleTransfer.money < res.rechargeDownLimit) {
                        alert_LHX({
                            hasBtn: 1,
                            msg: '圈存金额不足下限，请增加圈存金额！'
                        });
                    } else {
                        if (bleTransfer.isTransfer == true) {
                            ble.createOrder();
                        } else {
                            ble.createPaymentOrder(sendData.cardNo, sendData.balance);
                        }

                    }

                    break;
                case "101":
                    // 存在半条
                    bleTransfer.half = true;
                    bleTransfer.billno = res.billno;
                    bleTransfer.halfmoney = res.amount;
                    // alert(res.msg); //该卡存在一笔异常订单(单号[xxx]), 请先处理！
                    ble.countover();
                    alert_LHX({
                        hasBtn: 2,
                        msg: res.msg,
                        clickEvent: function() {
                            ble.sendTlvToDevice();
                        }
                    });
                    //弹出确认框，确定了再执行tlv()
                    break;
                default:
                    alert_LHX({
                        hasBtn: 1,
                        msg: res.msg
                    });
                    break;
            }
        });
    },

    //创建圈存订单
    createOrder: function() {
        console.log("创建圈存订单");
        var sendData = {
            cardNo: bleTransfer.card.cardNo, //卡号
            cardArea: bleTransfer.card.networkNo, //网络号
            money: bleTransfer.money, //圈存金额
            balance: bleTransfer.card.balance, //余额
        };

        bleAjaxGet('transfer/createOrder/', sendData, function(res) {
            if (res.respCode == "00") {
                // signature validatiton start --
                // 判断sig, 验证签名
                if (!res.sig) {
                    alert_LHX({
                        hasBtn: 1,
                        msg: '验证错误'
                    });
                    return;
                }

                var return_sig = res.sig;
                delete res.sig;
                var default_data = {
                    token: token
                };
                //alert(token);
                var sig = reckonSigGet(default_data, res);
                //alert(sig);
                if (return_sig != sig) {
                    alert_LHX({
                        hasBtn: 1,
                        msg: '验签失败'
                    });
                    return;
                }
                // -- signature validatiton end

                //保存订单号
                bleTransfer.billno = res.billno;
                ble.sendTlvToDevice();
            } else {
                alert_LHX({
                    hasBtn: 1,
                    msg: res.msg
                });
            }
        });
    },

    //获取圈存指令集
    checkInstru: function(data) {
        console.log("获取圈存指令集");
        var sendData = {
            orderNo: bleTransfer.billno,
            loadType: 1, //1:蓝牙|2:NFC
            instructionResps: data.substr(16, data.length - 18)
        };

        bleAjaxGet('transfer/checkInstru/', sendData, function(res) {　　
            if (res.respCode == "00") {
                // signature validatiton start --
                // 判断sig, 验证签名
                if (!res.sig) {
                    alert_LHX({
                        hasBtn: 1,
                        msg: '验证错误'
                    });
                    return;
                }

                var return_sig = res.sig;
                delete res.sig;
                var default_data = {
                    token: token
                };
                //alert(token);
                var sig = reckonSigGet(default_data, res);
                // alert(sig);
                if (return_sig != sig) {
                    alert_LHX({
                        hasBtn: 1,
                        msg: '验签失败'
                    });
                    return;
                }
                // -- signature validatiton end
                var tlv = convertToBluetoothChannel(res.instructions);
                ble.sendDataInit("confirm", convertToBluetoothProtocol(tlv));
            } else {
                alert_LHX({
                    hasBtn: 1,
                    msg: res.msg
                });
            }
        });
    },

    //确认圈存结果
    transferConfirm: function(data) {
        console.log("确认圈存结果");
        var sendData = {
            orderNo: bleTransfer.billno,
            loadType: 1, //1:蓝牙|2:NFC
            instructionResps: data.substr(16, data.length - 18)
        };

        bleAjaxGet('transfer/confirm/', sendData, function(res) {
            if (res.respCode == "00") {
                // signature validatiton start --
                // 判断sig, 验证签名
                if (!res.sig) {
                    alert_LHX({
                        hasBtn: 1,
                        msg: '验证错误'
                    });
                    return;
                }

                var return_sig = res.sig;
                delete res.sig;
                var default_data = {
                    token: token
                };
                //alert(token);
                var sig = reckonSigGet(default_data, res);
                //alert(sig);
                if (return_sig != sig) {
                    alert_LHX({
                        hasBtn: 1,
                        msg: '验签失败'
                    });
                    return;
                }
                // -- signature validatiton end
                //圈存确认完毕
                if (bleTransfer.half && !bleTransfer.handling) {
                    //处理完半条，返回上一次的获取上下限
                    bleTransfer.half = false;
                    ble.countover();
                    alert_LHX({
                        hasBtn: 2,
                        msg: "异常圈存订单处理完毕，是否继续当前订单处理？",
                        clickEvent: function() {
                            ble.resetCountdown();
                            ble.queryTransferLimit();
                        }
                    });
                } else {
                    bleTransfer.success = true;
                    ble.sendDataInit("readCard");
                }
            } else {
                alert_LHX({
                    hasBtn: 1,
                    msg: res.msg
                });
            }
        });
    },

    //圈存成功
    transferSuccess: function(data) {
        if (bleTransfer.handling) {
            //异常处理成功
            bleTransfer.callback(bleTransfer.newBalance);
        } else {
            setCookie("lastTransferMoney", bleTransfer.money); //储存本次充值金额作为记录
            $.StandardPost('transfer/toRechargeResult', {
                cardNo: bleTransfer.card.cardNo, //卡号
                orgBalance: bleTransfer.card.balance, //圈存前的余额
                balance: bleTransfer.money, //圈存的金额
                vehiclePlate: bleTransfer.card.vehPlane, //车牌号
                tlv: data
            });
        }
    },

    sendTlvToDevice: function() {
        var money = bleTransfer.half ? bleTransfer.halfmoney : bleTransfer.money;
        var tlv = "c201";
        tlv += (bleTransfer.card.versionNo >= 64) ? "3d00803b810700a40000021001020b0020000006313233343536" : "3a008038810700a4000002100102080020000003888888";
        tlv += "0310805001020b0100000000099030000001";
        tlv += "0411805000020b01" + MoneyToStr16(money, 8) + "09903000000110";
        ble.sendDataInit("transfer", convertToBluetoothProtocol(tlv));
    },

    sendRecordFile: function(vlp, cardNo, expiredate, versionNo) {
        ble.recordfile = {
            pin: false,
            vlp: vlp,
            cardNo: cardNo,
            expiredate: expiredate,
            tradelists: ""
        };

        //先解pin
        var tlv;
        if (versionNo >= 64) {
            tlv = "338013c2011000800d010b0020000006313233343536e6";
        } else {
            tlv = "338010c2010c00800a0108002000000388888877";
        }

        ble.sendDataInit("recordFile", [tlv]);
    },

    send0018Info: function() {
        if (ble.recordfile.pin) {
            console.log("send0018Info");
            var buf = ble.recordfile.tradelists;
            buf = buf.substr(0, buf.length - 1);
            $.ajax({
                url: 'card/send0018Info',
                type: 'POST',
                dataType: 'json',
                data: {
                    vlp: ble.recordfile.vlp,
                    cardNo: ble.recordfile.cardNo,
                    expiredate: ble.recordfile.expiredate,
                    buf: buf
                },
                cache: false,
                timeout: 30000
            });
        } else {
            ble.recordfile.pin = true;
            // alert(" ble.recordfile.pin:"+ble.recordfile.pin )
            ble.sendDataInit("recordFile", getRecordFileTlv());
        }
    },
    // 创建充值订单并发起微信支付
    createPaymentOrder: function(cardNo, money) {
        console.log('step into createOrder()');
        var orgBalance = cardInfo[1];
        var vehiclePlate = cardInfo[2];

        var data = {
            cardNo: cardNo,
            money: money,
            createFrom: 2
                //money: 1
        };

        var time = (new Date()).valueOf();
        var sig_param = data;
        sig_param.time = time;
        sig_param.token = token;
        data.sig = reckonSig(sig_param);

        $(".loading").show();
        $.ajax({
            url: 'payment/createOrder/' + time,
            // url: 'http://demo.hgits.cn/ArsWechatServer4JX/payment/createOrder',
            type: 'POST',
            dataType: 'json',
            data: data,
            cache: false,
            timeout: 20000 * bleTimeout,
            success: function(r) {
                console.log(r);
                $(".loading").hide();

                if (r.respCode != "00") {
                    alert_LHX({
                        hasBtn: 1,
                        msg: r.msg
                    });
                    return;
                }
                //判断sig, 验证签名
                if (!r.sig) {
                    alert_LHX({
                        hasBtn: 1,
                        msg: '验证错误'
                    });
                    return;
                }

                var return_sig = r.sig;
                delete r.sig;
                var default_data = {
                    token: token
                };
                var sig = reckonSigGet(default_data, r);
                if (return_sig != sig) {
                    alert_LHX({
                        hasBtn: 1,
                        msg: '验签失败'
                    });
                    return;
                }

                var orderNo = r.orderNo;
                ble.countover();
                $(".mask_layer, .mask_layer > div").addClass('none');
                
                wx.chooseWXPay({
                    timestamp: r.timeStamp, // 支付签名时间戳
                    nonceStr: r.nonceStr, // 支付签名随机串，不长于 32 位
                    package: r.package, // 统一支付接口返回的prepay_id参数值，提交格式如：prepay_id=***）
                    signType: r.signType, // 签名方式，默认为'SHA1'，使用新版支付需传入'MD5'
                    paySign: r.paySign, // 支付签名
                    // appId: r.appId,
                    success: function(res) {
                        //alert("支付成功");
                        setCookie("lastRechargeMoney", money); //储存本次充值金额作为记录                           
                        ble.paymentConfirm(orderNo);                        
                    },
                    cancel: function() {
                        // 用户取消支付后执行的回调函数
                        ble.countover();
                        $(".mask_layer, .mask_layer > div").addClass('none');
                    },
                    fail: function() {
                        // 用户取消支付后执行的回调函数
                        //alert("支付失败");
                        ble.countover();
                        $(".mask_layer, .mask_layer > div").addClass('none');
                        alert_LHX({
                            hasBtn: 1,
                            msg: "系统异常，支付失败，请重试！"
                        });
                        


                    },
                });

            },
            error: function(e) {
                $(".loading").hide();
                if (e.statusText == "timeout" || window.navigator.onLine == false) {
                    alert_LHX({
                        msg: bleInfo.NET_TIMEOUT
                    });
                    return false;
                }
                alert_LHX({
                    hasBtn: 1,
                    msg: bleInfo.SERVER_ERROR
                });
            }

        });
    },
    // 查询充值订单状态
    paymentConfirm: function(orderNo) {
        $(".loading").show();
        var data = {
            orderNo: orderNo
        };
        var time = (new Date()).valueOf();
        var sig_param = data;
        sig_param.time = time;
        sig_param.token = token;
        data.sig = reckonSig(sig_param);
        $.ajax({
            url: 'payment/confirm/' + time,
            type: 'POST',
            dataType: 'json',
            data: data,
            cache: false,
            timeout: 20000 * bleTimeout,            
            success: function(r) {
                console.log(r);
                $(".loading").hide();
                paymentConfirmTimes ++; //统计订单确认查询的次数
                //alert(r.respCode);                
                if (r.respCode != "00") {
                    if (paymentConfirmTimes < 5){
                        ble.paymentConfirm(orderNo);// 未查够5次，继续查订单状态
                    }else if(r.respCode == "01"){
                        alert_LHX({
                            hasBtn: 1,
                            msg: '订单未到账'
                        });
                    }
                    return false;
                }

                //判断sig, 验证签名
                if (!r.sig) {
                    alert_LHX({
                        hasBtn: 1,
                        msg: '验证错误'
                    });
                    return;
                }

                var return_sig = r.sig;
                delete r.sig;

                var default_data = {
                    token: token
                };
                var sig = reckonSigGet(default_data, r);
                if (return_sig != sig) {
                    alert_LHX({
                        hasBtn: 1,
                        msg: '验签失败'
                    });
                    return;
                }

                //订单显示已到账
                //保存订单号
                bleTransfer.billno = r.billno;
                console.log("bleTransfer.billno="+ bleTransfer.billno);
                ble.maskBoxShow("debbting_box");
                ble.sendTlvToDevice();
            },
            error: function(e) {
                $(".loading").hide();
                paymentConfirmTimes ++; //统计订单确认查询的次数
                if (e.statusText == "timeout" || window.navigator.onLine == false) {
                    alert_LHX({
                        msg: bleInfo.NET_TIMEOUT
                    });
                    return false;
                }
                alert_LHX({
                    msg: bleInfo.SERVER_ERROR
                });

            }
        });
    }
};

function bleAjaxGet(url, sendData, success) {
    // signature start --
    var time = (new Date()).valueOf();
    var sig_param = sendData;
    sig_param.time = time;
    sig_param.token = token;
    console.log(sig_param);
    sendData.sig = reckonSig(sig_param);
    // -- signature end
    bleAjax = $.ajax({　　
        url: url + time,
        timeout: 20000 * bleTimeout,
        type: 'get',
        data: sendData,
        dataType: 'json',
        beforeSend: function () {
            $(".loading").show();
        },
        success: success,
        complete: function(XMLHttpRequest, status) {
            $(".loading").hide();　　　　
            if (status == 'timeout') {　　　　　
                bleAjax.abort();　　　　　
                alert_LHX({
                    hasBtn: 1,
                    msg: bleInfo.NET_TIMEOUT
                });　　　　
            }else if (status == "500"){
                alert_LHX({
                    hasBtn: 1,
                    msg: bleInfo.SERVER_ERROR
                });
            }　　
        }
    });
}

function getRecordFileTlv() {
    var arr = [];
    for (var i = 0; i < 50; i++) {
        //80+len1+01+len2+str
        var code = "8007010500B2";
        if (i < 15) {
            code += "0";
        }
        code += (i + 1).toString(16) + "C400";
        var tlv = convertToBluetoothChannel(code);
        var a = convertToBluetoothProtocol(tlv);
        arr.push(a[0]);
    }
    return arr;
}


var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var base64DecodeChars = new Array(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);

function encode(str) {
    return base64encode(bytes2Str10(Str162Bytes(str)));
}

function decode(str) {
    return Bytes2Str16(Str102Bytes(base64decode(str))).toUpperCase();
}

/**
 * base64编码
 * @param {Object} str
 */
function base64encode(str) {
    var out = "",
        i = 0,
        len = str.length;
    var c1, c2, c3;
    while (i < len) {
        c1 = str.charCodeAt(i++) & 0xff;
        if (i == len) {
            out += base64EncodeChars.charAt(c1 >> 2);
            out += base64EncodeChars.charAt((c1 & 0x3) << 4);
            out += "==";
            break;
        }
        c2 = str.charCodeAt(i++);
        if (i == len) {
            out += base64EncodeChars.charAt(c1 >> 2);
            out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
            out += base64EncodeChars.charAt((c2 & 0xF) << 2);
            out += "=";
            break;
        }
        c3 = str.charCodeAt(i++);
        out += base64EncodeChars.charAt(c1 >> 2);
        out += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));
        out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));
        out += base64EncodeChars.charAt(c3 & 0x3F);
    }
    return out;
}

/**
 * base64解码
 * @param {Object} str
 */
function base64decode(str) {
    var c1, c2, c3, c4;
    var out = "",
        i = 0,
        len = str.length;
    while (i < len) {
        /* c1 */
        do {
            c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
        }
        while (i < len && c1 == -1);
        if (c1 == -1)
            break;
        /* c2 */
        do {
            c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
        }
        while (i < len && c2 == -1);
        if (c2 == -1)
            break;
        out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
        /* c3 */
        do {
            c3 = str.charCodeAt(i++) & 0xff;
            if (c3 == 61)
                return out;
            c3 = base64DecodeChars[c3];
        }
        while (i < len && c3 == -1);
        if (c3 == -1)
            break;
        out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));
        /* c4 */
        do {
            c4 = str.charCodeAt(i++) & 0xff;
            if (c4 == 61)
                return out;
            c4 = base64DecodeChars[c4];
        }
        while (i < len && c4 == -1);
        if (c4 == -1)
            break;
        out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
    }
    return out;
}

/**
 * utf16转utf8
 * @param {Object} str
 */
function utf16to8(str) {
    var out = "",
        i, len = str.length,
        c;
    for (i = 0; i < len; i++) {
        c = str.charCodeAt(i);
        if ((c >= 0x0001) && (c <= 0x007F)) {
            out += str.charAt(i);
        } else if (c > 0x07FF) {
            out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
            out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
            out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
        } else {
            out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
            out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
        }
    }
    return out;
}

/**
 * utf8转utf16
 * @param {Object} str
 */
function utf8to16(str) {
    var out = "",
        i = 0,
        len = str.length,
        c;
    var char2, char3;
    while (i < len) {
        c = str.charCodeAt(i++);
        switch (c >> 4) {
            case 0:
            case 1:
            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
                // 0xxxxxxx
                out += str.charAt(i - 1);
                break;
            case 12:
            case 13:
                // 110x xxxx 10xx xxxx
                char2 = str.charCodeAt(i++);
                out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
                break;
            case 14:
                // 1110 xxxx10xx xxxx10xx xxxx
                char2 = str.charCodeAt(i++);
                char3 = str.charCodeAt(i++);
                out += String.fromCharCode(((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));
                break;
        }
    }
    return out;
}

// 16进制的字符串转换byte数组
function Str162Bytes(str) {
    var pos = 0;
    var len = str.length;
    if (len % 2 != 0) {
        return null;
    }
    len /= 2;
    var hexA = [];
    for (var i = 0; i < len; i++) {
        var s = str.substr(pos, 2);
        var v = parseInt(s, 16);
        hexA.push(v);
        pos += 2;
    }
    return hexA;
}

function Bytes2Str16(arr) {
    var str = "";
    for (var i = 0; i < arr.length; i++) {
        var tmp = arr[i].toString(16);
        if (tmp.length == 1) {
            tmp = "0" + tmp;
        }
        str += tmp;
    }
    return str;
}

function Byte2Str16(byte) {
    var str = byte.toString(16);
    if (str.length == 1) {
        str = "0" + str;
    }
    return str;
}

// byte数组转换普通字符串
function bytes2Str10(array) {
    var result = "";
    for (var i = 0; i < array.length; i++) {
        result += String.fromCharCode(parseInt(array[i]));
    }
    return result;
}

// 普通字符串转换长byte数组
function Str102Bytes(str) {
    var hexA = [];
    for (var i = 0; i < str.length; i++) {
        var s = str.charCodeAt(i);
        hexA.push(s);
    }
    return hexA;
}

function addBcc(str) {
    var byteArray = Str162Bytes(str);
    var len = byteArray.length;
    for (var i = 0; i < len; i++) {
        byteArray[len] ^= byteArray[i];
    }
    return Bytes2Str16(byteArray);
}

//TLV指令层
function convertToBluetoothTlv(str) {
    var len = str.length / 2;
    return "800901" + Byte2Str16(len) + str;
}

//通道指令层
function convertToBluetoothChannel(str) {
    var len = str.length / 2;
    return "C201" + Byte2Str16(len) + "00" + str;
}

//最外层
function convertToBluetoothProtocol(str) {
    var maxDataCount = 95;
    var len = str.length / 2;
    var multi = len / maxDataCount;
    if (len % maxDataCount != 0) {
        multi++;
    }
    var pgkLen;
    var pgkIndex = 1;
    var ctl;
    var array = [];
    var strPgkIndex = 0;
    while (len > 0) {
        if (len > maxDataCount) {
            pgkLen = maxDataCount;
        } else {
            pgkLen = len;
        }
        if (pgkIndex == 1) {
            ctl = multi - pgkIndex & 127 | 128;
        } else {
            ctl = multi - pgkIndex & 127;
        }
        var s = Byte2Str16(ctl) + Byte2Str16(pgkLen) + str.substr(strPgkIndex, pgkLen * 2);

        s = "33" + addBcc(s);
        array.push(s);
        pgkIndex++;
        strPgkIndex += pgkLen * 2;
        len -= pgkLen;
    }
    return array;
}

function MoneyToStr16(num, n) {
    num = (num - 0).toString(16);
    return (Array(n).join(0) + num).slice(-n);
}

String.prototype.replaceAll = function(s1, s2) {
    return this.replace(new RegExp(s1, "gm"), s2);
};

//用post方法跳转页面
$.extend({
    StandardPost: function(url, args) {
        var body = $(document.body),
            form = $("<form method='post'></form>"),
            input;
        form.attr({
            "action": url
        });
        $.each(args, function(key, value) {
            input = $("<input type='hidden'>");
            input.attr({
                "name": key
            });
            input.val(value);
            form.append(input);
        });

        form.appendTo(document.body);
        form.submit();
        document.body.removeChild(form[0]);
    }
});

function getCardInfo(tlv) {
    $(".loading").show();
    $.ajax({
        url: 'card/cardInfo',
        type: 'GET',
        dataType: 'json',
        data: {
            tlv: tlv
        },
        cache: false,
        timeout: 25000 * bleTimeout,
        success: function(r) {
            $(".loading").hide();
            if (r.respCode != "00") {
                errorToast(r.msg, 3);
                return;
            }


            if (bleTransfer) {
                //圈存读卡完成或者圈存成功读卡
                if (bleTransfer.init) {

                    if (bleTransfer.success && bleTransfer.handling) {
                        bleTransfer.newBalance = r.cardInfo.balance;
                        ble.transferSuccess();
                        return;
                    }

                    bleTransfer.card = r.cardInfo;
                    if (bleTransfer.card.cardNo != ble.opts.cardNo) {
                        alert_LHX({
                            hasBtn: 1,
                            msg: bleInfo.CARDNO_DIFFERENT
                        });
                        return;
                    }
                    bleTransfer.card.endTime = bleTransfer.card.endTime.replaceAll('-', '');
                    if (bleTransfer.half) {
                        ble.sendTlvToDevice();
                    } else {
                        ble.queryTransferLimit();
                    }
                }
                return;
            }

            var cardType = r.cardInfo.type == 22 ? carTypeArray[1] : carTypeArray[2];
            var cardNo = r.cardInfo.cardNo;
            var vehPlane = r.cardInfo.vehPlane;
            var expiredate = r.cardInfo.endTime;
            $("#cardType").html(cardType); // 卡类型
            $("#queryVpl").html(vehPlane); // 车牌

            $("#queryNum").html(cardNumFormat("3601" + cardNo)); //卡号
            $("#queryEndDate").html("到期：" + r.cardInfo.startTime + "至" + expiredate); // 有效期

            // 记账卡，卡内余额和卡账户余额不显示
            if (r.cardInfo.type == 23) {
                $(".query_result_body").addClass('none');
                $(".queryText").html("");
                $("#cardBalance").html(""); // 卡余额
            } else {
                $(".queryText").html("卡内余额");
                $("#cardBalance").html("¥" + (r.cardInfo.balance / 100).toFixed(2)); // 卡余额
                //("r.amount.respCode:" + r.amount.respCode);
                // 查询余额信息异常 查询本地是否有上一次的记录
                if (r.amount.respCode != "00" || r.amount.balance == "") {
                    var lastDate = getCookie("amountDate");
                    var lastBalance = getCookie("amountBalance");
                    var lastCardNo = getCookie("amountCardNo");

                    // cookie中不存在上一次查询的记录
                    if (lastDate == "" || lastBalance == "" || lastCardNo != cardNo) {
                        $(".load-normal").hide();
                        $(".load-error").show();
                    } else {
                        // 显示cookie中上一次查询的记录
                        $("#amountBalance").html((lastBalance / 100).toFixed(2));
                        $("#amountDate").html(lastDate);
                        $(".load-normal").show();
                        $(".load-error").hide();
                    }
                } else {

                    // 查询余额信息正常
                    var date = formatDate();
                    var today = date[0] + "年" + date[1] + "月" + date[2] + "日";
                    setCookie("amountDate", today);
                    setCookie("amountBalance", r.amount.balance);
                    setCookie("amountCardNo",r.amount.cardNo);
                    $("#amountBalance").html((r.amount.balance / 100).toFixed(2));
                    $("#amountDate").html(today);

                    if (r.amount.getTradeInfo == "Y" && r.cardInfo.issuerPro == "江西") {
                        ble.sendRecordFile(vehPlane, cardNo, expiredate, r.cardInfo.versionNo);
                    }
                }
            }

            ble.countover();

            $(".mask_layer").addClass("none");
            $("#queryResult").removeClass("none");
        },
        error: function(e) {
            $(".loading").hide();
            alert_LHX({
                hasBtn: 1,
                msg: bleInfo.NET_TIMEOUT
            });
        }
    });
}